# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from .base import BASIC_STRATEGY

class MACD(BASIC_STRATEGY):
    def __init__(self):
        pass

    def update(self, date_df):
        return self.MACD_rt(date_df)

    def MACD(self, data_df, fast=12, slow=26, signal_period=9):
        """
        计算MACD买卖策略
        参数：
            df: 包含价格数据的DataFrame，需包含'close'列
            fast: 快线周期（默认12）
            slow: 慢线周期（默认26）
            signal_period: 信号线周期（默认9）
        返回：
            添加策略信号的DataFrame
        """
        df = data_df.copy()
        # 计算EMA
        df['EMA_fast'] = df['成交价'].ewm(span=fast, adjust=False).mean()
        df['EMA_slow'] = df['成交价'].ewm(span=slow, adjust=False).mean()

        # 计算MACD和信号线
        df['MACD'] = df['EMA_fast'] - df['EMA_slow']
        df['Signal'] = df['MACD'].ewm(span=signal_period, adjust=False).mean()

        # 生成交易信号（1: 买入， -1: 卖出， 0: 无操作）
        df['Signal_Cross'] = np.where(df['MACD'] > df['Signal'], 1, -1)
        df['Position'] = df['Signal_Cross'].diff()

        # 标记买卖点
        df['Buy_Signal'] = np.where((df['Position'] == -2), df['成交价'], 0)
        df['Sell_Signal'] = np.where((df['Position'] == 2), df['成交价'], 0)
        return df

    def MACD_rt(self, data_df, fast=12, slow=26, signal_period=9):
        df = data_df.copy()
        # 第一次计算macd
        if "EMA_fast" not in df.columns:
            # 计算EMA
            df['EMA_fast'] = df['成交价'].ewm(span=fast, adjust=False).mean()
            df['EMA_slow'] = df['成交价'].ewm(span=slow, adjust=False).mean()

            # 计算MACD和信号线
            df['MACD'] = df['EMA_fast'] - df['EMA_slow']
            df['Signal'] = df['MACD'].ewm(span=signal_period, adjust=False).mean()

            # 生成交易信号（1: 买入， -1: 卖出， 0: 无操作）
            df['Signal_Cross'] = np.where(df['MACD'] > df['Signal'], 1, -1)
            df['Position'] = df['Signal_Cross'].diff()

            # 标记买卖点
            df['Buy_Signal'] = np.where((df['Position'] == -2), df['成交价'], 0)
            df['Sell_Signal'] = np.where((df['Position'] == 2), df['成交价'], 0)
        # 增量更新macd指标
        else:
            df.loc[df.index[-1], 'EMA_fast'] = df.loc[df.index[-1], '成交价'] * 2/(fast+1) + df.loc[df.index[-2], 'EMA_fast'] *(fast-1)/(fast+1)
            df.loc[df.index[-1], 'EMA_slow'] = df.loc[df.index[-1], '成交价'] * 2/(slow+1) + df.loc[df.index[-2], 'EMA_fast'] *(slow-1)/(slow+1)

            # 计算MACD和信号线
            df.loc[df.index[-1], 'MACD'] = df.loc[df.index[-1], 'EMA_fast'] - df.loc[df.index[-1], 'EMA_slow']
            df.loc[df.index[-1], 'Signal'] = df.loc[df.index[-1], 'MACD'] * 2/(signal_period+1) + df.loc[df.index[-2], 'MACD'] * (signal_period-1)/(signal_period+1)

            # 生成交易信号（1: 买入， -1: 卖出， 0: 无操作）
            df.loc[df.index[-1], 'Signal_Cross'] = 1 if df.loc[df.index[-1], 'MACD'] > df.loc[df.index[-1], 'Signal'] else -1
            df.loc[df.index[-1], 'Position'] = df.loc[df.index[-1], 'Signal_Cross'] - df.loc[df.index[-2], 'Signal_Cross']

            # 标记买卖点
            df.loc[df.index[-1], 'Buy_Signal'] = df.loc[df.index[-1], '成交价'] if df.loc[df.index[-1], 'Position'] == -2 else 0
            df.loc[df.index[-1], 'Sell_Signal'] = df.loc[df.index[-1], '成交价'] if df.loc[df.index[-1], 'Position'] == 2 else 0
        return df

class KDJ(BASIC_STRATEGY):
    def __init__(self):
        pass

    def update(self, data_df, n=9, m1=3, m2=3):
        data = self.calculate_kdj(data_df, n=9, m1=3, m2=3)
        data = self.detect_kdj_cross(data)
        return data

    def calculate_kdj(self, data_df, n=9, m1=3, m2=3):
        """
        计算KDJ指标
        :param data: DataFrame，需包含['high', 'low', 'close']列
        :param n: RSV计算周期（默认9天）
        :param m1: K值平滑周期（默认3天）
        :param m2: D值平滑周期（默认3天）
        :return: 添加['K', 'D', 'J']列的DataFrame
        """
        # 计算最低价和最高价的滚动窗口
        data = data_df.copy()
        low_min = data['low'].rolling(n).min()
        high_max = data['high'].rolling(n).max()

        # 计算RSV
        rsv = (data['close'] - low_min) / (high_max - low_min) * 100
        rsv.fillna(50, inplace=True)  # 初始值填充

        # 初始化K、D值
        data['K'] = rsv.ewm(alpha=1 / m1, adjust=False).mean()  # 等价于公式中的递归计算
        data['D'] = data['K'].ewm(alpha=1 / m2, adjust=False).mean()
        data['J'] = 3 * data['K'] - 2 * data['D']

        return data

    def detect_kdj_cross(self, data):
        """
        检测KDJ金叉和死叉
        :param data: 必须包含['K', 'D']列
        :return: 添加['golden_cross', 'death_cross']列的DataFrame
        """
        # 金叉：K线上穿D线 金叉买入
        data['golden_cross'] = (data['K'] > data['D']) & (data['K'].shift(1) <= data['D'].shift(1))
        data['Buy_Signal'] = (data['K'] > data['D']) & (data['K'].shift(1) <= data['D'].shift(1))
        # 超强金叉
        golden_cross_threshold = 30.0
        data['super_golden_cross'] = (data['K'] > data['D']) & (data['K'].shift(1) <= data['D'].shift(1)) & (data['K'] <= golden_cross_threshold) & (data['D'] <= golden_cross_threshold)
        # data['Buy_Signal'] = (data['K'] > data['D']) & (data['K'].shift(1) <= data['D'].shift(1)) & (data['K'] <= golden_cross_threshold) & (data['D'] <= golden_cross_threshold)

        # 死叉：K线下穿D线 死叉卖出
        data['death_cross'] = (data['K'] < data['D']) & (data['K'].shift(1) >= data['D'].shift(1))
        data['Sell_Signal'] = (data['K'] < data['D']) & (data['K'].shift(1) >= data['D'].shift(1))
        # 超强死叉
        death_cross_threshold = 70.0
        data['super_death_cross'] = (data['K'] < data['D']) & (data['K'].shift(1) >= data['D'].shift(1)) & (data['K'] >= death_cross_threshold) & (data['D'] >= death_cross_threshold)
        # data['Sell_Signal'] = (data['K'] < data['D']) & (data['K'].shift(1) >= data['D'].shift(1)) & (data['K'] >= death_cross_threshold) & (data['D'] >= death_cross_threshold)

        # # 增加回测需要的列
        # data['成交价'] = data['close']
        # data['日期'] = data['date'].str[:10]
        # data['时间'] = data['date'].str[11:19]
        return data

class RSI(BASIC_STRATEGY):
    def __init__(self, period=14, overbought=70, oversold=30):
        """
        初始化RSI策略
        :param period: RSI计算周期，默认为14
        :param overbought: 超买阈值，默认为70
        :param oversold: 超卖阈值，默认为30
        """
        self.period = period
        self.overbought = overbought
        self.oversold = oversold
        self.prev_close = None
        self.gains = []
        self.losses = []
        self.rsi_values = []
        self.initialized = False
        self.data_buffer = pd.DataFrame()

    def _calculate_rsi(self, new_close):
        """
        计算RSI值（内部方法）
        :param new_close: 新的收盘价
        :return: 当前RSI值
        """
        if self.prev_close is None:
            self.prev_close = new_close
            return None

        price_diff = new_close - self.prev_close
        self.prev_close = new_close

        gain = price_diff if price_diff > 0 else 0
        loss = -price_diff if price_diff < 0 else 0

        self.gains.append(gain)
        self.losses.append(loss)

        # 保持窗口大小为period
        if len(self.gains) > self.period:
            self.gains.pop(0)
            self.losses.pop(0)

        # 只有在积累了足够数据后才计算RSI
        if len(self.gains) == self.period:
            avg_gain = sum(self.gains) / self.period
            avg_loss = sum(self.losses) / self.period

            if avg_loss == 0:
                rsi = 100
            else:
                rs = avg_gain / avg_loss
                rsi = 100 - (100 / (1 + rs))

            self.rsi_values.append(rsi)
            return rsi

        return None

    def update(self, new_data):
        """
        更新策略状态并生成信号
        :param new_data: 新的分钟数据，DataFrame格式
        :return: 包含买卖信号的DataFrame
        """
        # 合并新数据到缓冲区
        self.data_buffer = new_data

        # 初始化输出DataFrame
        signals = new_data.copy()
        signals['Buy_Signal'] = 0
        signals['Sell_Signal'] = 0

        # 如果没有足够数据初始化，直接返回
        if len(self.data_buffer) < self.period + 1:
            return signals

        # 计算RSI
        for idx, row in new_data.iterrows():
            rsi = self._calculate_rsi(row['close'])

            # 只有在有RSI值时才生成信号
            if rsi is not None and len(self.rsi_values)>1:
                last_rsi = self.rsi_values[-2] if len(self.rsi_values) > 0 else None

                # 生成买卖信号
                if last_rsi is not None:
                    if last_rsi < self.oversold and rsi >= self.oversold:
                        signals.loc[signals.index[-1], 'Buy_Signal'] = 1
                    elif last_rsi > self.overbought and rsi <= self.overbought:
                        signals.loc[signals.index[-1], 'Sell_Signal'] = 1
                    else:
                        pass
        signals.fillna(0, inplace=True)
        return signals

class DMI(BASIC_STRATEGY):
    def update(self, data):
        period = 14  # 默认周期为14

        # 计算 +DM 和 -DM
        data['+DM'] = data['high'].diff()
        data['-DM'] = data['low'].diff()
        # data['+DM'] = np.where((data['+DM'] > 0) & (data['+DM'] > data['-DM']), data['+DM'], 0)
        # data['-DM'] = np.where((data['-DM'] < 0) & (data['-DM'] < data['+DM']), -data['-DM'], 0)

        data['+DM'] = np.where((data['+DM'] > 0) & (data['+DM'] > abs(data['-DM'])), data['+DM'], 0)
        data['-DM'] = np.where((data['-DM'] < 0) & ((-data['-DM']) < abs(data['+DM'])), -data['-DM'], 0)

        # 计算 TR（真实波动范围）
        data['TR'] = pd.DataFrame({
            'HL': data['high'] - data['low'],
            'HC': (data['high'] - data['close'].shift()).abs(),
            'LC': (data['low'] - data['close'].shift()).abs()
        }).max(axis=1)

        # 计算 +DI 和 -DI
        data['+DI'] = data['+DM'].rolling(window=period).mean() / data['TR'].rolling(window=period).mean() * 100
        data['-DI'] = data['-DM'].rolling(window=period).mean() / data['TR'].rolling(window=period).mean() * 100

        # 计算 DX
        data['DX'] = (data['+DI'] - data['-DI']).abs() / (data['+DI'] + data['-DI']) * 100

        # 计算 ADX
        data['ADX'] = data['DX'].rolling(window=period).mean()

        # 生成买卖信号
        # 买入信号：+DI 上穿 -DI
        data['Buy_Signal'] = np.where((data['+DI'] > data['-DI']) & (data['+DI'].shift() <= data['-DI'].shift()) &
                              (data['ADX'] > 25), 1,
                                      0)
        # 卖出信号：+DI 下穿 -DI
        data['Sell_Signal'] = np.where((data['+DI'] < data['-DI']) & (data['+DI'].shift() >= data['-DI'].shift()) &
                              (data['ADX'] > 25),
                                       1, 0)
        return data

class DMA(BASIC_STRATEGY):
    def update(self, data):
        short_period = 10  # 短期移动平均线周期
        long_period = 50   # 长期移动平均线周期

        # 计算短期和长期移动平均线
        data['MA_short'] = data['close'].rolling(window=short_period).mean()
        data['MA_long'] = data['close'].rolling(window=long_period).mean()

        # 计算 DMA（平均差）
        data['DIF'] = data['MA_short'] - data['MA_long']
        data['AMA'] = data['DIF'].rolling(window=10).mean()

        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['DIF'] > data['AMA']) & (data['DIF'].shift() <= data['AMA'].shift()), 1, 0)
        data['Sell_Signal'] = np.where((data['DIF'] < data['AMA']) & (data['DIF'].shift() >= data['AMA'].shift()), 1, 0)

        return data

class TRIX(BASIC_STRATEGY):
    def update(self, data):
        period = 12
        signal_period = 9
        data['EMA1'] = data['close'].ewm(span=period, adjust=False).mean()
        data['EMA2'] = data['EMA1'].ewm(span=period, adjust=False).mean()
        data['EMA3'] = data['EMA2'].ewm(span=period, adjust=False).mean()
        data['TRIX'] = data['EMA3'].pct_change() * 100

        # data['Buy_Signal'] = np.where(data['TRIX'] > 0, 1, 0)
        # data['Sell_Signal'] = np.where(data['TRIX'] < 0, 1, 0)

        # 计算信号线（Signal Line）
        data['Signal'] = data['TRIX'].ewm(span=signal_period, adjust=False).mean()

        # 生成买卖信号
        data['Buy_Signal'] = np.where(
            (data['TRIX'] > data['Signal']) & (data['TRIX'].shift() <= data['Signal'].shift()), 1, 0)
        data['Sell_Signal'] = np.where(
            (data['TRIX'] < data['Signal']) & (data['TRIX'].shift() >= data['Signal'].shift()), 1, 0)
        return data

class VR(BASIC_STRATEGY):
    def update(self, data):
        period = 26
        mavr_period = 6
        data['TH'] = np.where(data['close'] > data['close'].shift(), data['volume'], 0)
        data['TL'] = np.where(data['close'] < data['close'].shift(), data['volume'], 0)
        data['TQ'] = np.where(data['close'] == data['close'].shift(), data['volume'], 0)
        # 计算 N 日内的累计值
        data['TH'] = data['TH'].rolling(window=period).sum()
        data['TL'] = data['TL'].rolling(window=period).sum()
        data['TQ'] = data['TQ'].rolling(window=period).sum()
        # 计算 VR 值
        data['VR'] = 100 * (data['TH'] * 2 + data['TQ']) / (data['TL'] * 2 + data['TQ'])
        # 计算 VR 的 M 日平均值（VRMA）
        # data['VRMA'] = data['VR'].rolling(window=mavr_period).mean()

        # 买入信号：VR 从高位下降至 150 以下
        data['Buy_Signal'] = np.where((data['VR'] < 150) & (data['VR'].shift() >= 150), 1, 0)
        # 卖出信号：VR 从低位上升至 250 以上
        data['Sell_Signal'] = np.where((data['VR'] > 250) & (data['VR'].shift() <= 250), 1, 0)
        return data

class OBV(BASIC_STRATEGY):
    def update(self, data):
        obvma_period=10
        # 计算 OBV 值
        data['OBV'] = np.where(data['close'] > data['close'].shift(), data['volume'],
                               np.where(data['close'] < data['close'].shift(), -data['volume'], 0)).cumsum()

        # 计算 OBV 的移动平均线（OBVMA）
        data['OBVMA'] = data['OBV'].rolling(window=obvma_period).mean()

        # 生成买卖信号
        data['Buy_Signal'] = np.where(
            (data['OBV'] > data['OBVMA']) & (data['OBV'].shift() <= data['OBVMA'].shift()), 1, 0)
        data['Sell_Signal'] = np.where(
            (data['OBV'] < data['OBVMA']) & (data['OBV'].shift() >= data['OBVMA'].shift()), 1, 0)
        return data

class ASI(BASIC_STRATEGY):
    def update(self,data, period=6):
        # 计算 A, B, C, D
        data['A'] = (data['high'] - data['close'].shift()).abs()
        data['B'] = (data['low'] - data['close'].shift()).abs()
        data['C'] = (data['high'] - data['low'].shift()).abs()
        data['D'] = (data['close'].shift() - data['open'].shift()).abs()

        # 计算 E, F, G
        data['E'] = data['close'] - data['close'].shift()
        data['F'] = data['close'] - data['open']
        data['G'] = data['close'].shift() - data['open'].shift()

        # 计算 X
        data['X'] = data['E'] + 0.5 * data['F'] + data['G']

        # 计算 R 和 K
        data['K'] = data[['A', 'B']].max(axis=1)
        data['R'] = np.where(data['A'] == data['K'], data['A'] + 0.5 * data['B'] + 0.25 * data['D'],
                              np.where(data['B'] == data['K'], data['B'] + 0.5 * data['A'] + 0.25 * data['D'],
                                       data['C'] + 0.25 * data['D']))

        # 计算 SI
        data['SI'] = 50 * data['X'] / data['R'] * data['K'] / 3

        # 计算 ASI
        data['ASI'] = data['SI'].cumsum()

        # 计算 ASI 的移动平均线（ASIEMA）
        data['ASIEMA'] = data['ASI'].ewm(span=period, adjust=False).mean()

        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['ASI'] > data['ASIEMA']) & (data['ASI'].shift() <= data['ASIEMA'].shift()), 1, 0)
        data['Sell_Signal'] = np.where((data['ASI'] < data['ASIEMA']) & (data['ASI'].shift() >= data['ASIEMA'].shift()), 1, 0)
        return data

class EMV(BASIC_STRATEGY):
    def update(self, data):
        n = 14
        m = 9
        # 计算中间值 A 和 B
        data['A'] = (data['high'] + data['low']) / 2
        data['B'] = (data['high'].shift(1) + data['low'].shift(1)) / 2
        # 计算价格波动范围 C
        data['C'] = data['high'] - data['low']
        # 计算 EM
        data['EM'] = (data['A'] - data['B']) * data['C'] / data['volume']
        # 计算 EMV
        data['EMV'] = data['EM'].rolling(window=n).sum()
        # 计算 MAEMV
        data['MAEMV'] = data['EMV'].rolling(window=m).mean()
        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['EMV'] > 0) & (data['EMV'].shift(1) <= 0), 1, 0)
        data['Sell_Signal'] = np.where((data['EMV'] < 0) & (data['EMV'].shift(1) >= 0), 1, 0)
        return data

class WVAD(BASIC_STRATEGY):
    def update(self, data):
        n = 24
        m = 6
        short_ma = 5
        long_ma = 14
        # 计算 A、B 和 V
        data['A'] = data['close'] - data['open']
        data['B'] = data['high'] - data['low']
        data['V'] = data['volume']  # 假设数据中的成交量单位为金额
        # 计算每日的 WVAD 值
        data['WVAD'] = (data['A'] / data['B']) * data['V']
        # 计算 N 日累加值
        data['WVAD'] = data['WVAD'].rolling(window=n).sum()
        # 计算移动平均线
        data['MAWVAD'] = data['WVAD'].rolling(window=m).mean()
        # 计算短期和长期移动平均线
        data['WVAD_short'] = data['WVAD'].rolling(window=short_ma).mean()
        data['WVAD_long'] = data['WVAD'].rolling(window=long_ma).mean()
        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['WVAD_short'] > data['WVAD_long']) &
                                      (data['WVAD_short'].shift() <= data['WVAD_long'].shift()), 1, 0)
        data['Sell_Signal'] = np.where((data['WVAD_short'] < data['WVAD_long']) &
                                       (data['WVAD_short'].shift() >= data['WVAD_long'].shift()), 1, 0)
        return data

class CCI(BASIC_STRATEGY):
    def update(self, data):
        period=20
        # 计算典型价格（TP）
        data['TP'] = (data['high'] + data['low'] + data['close']) / 3
        # 计算简单移动平均（SMA）
        data['SMA'] = data['TP'].rolling(window=period).mean()
        # 计算平均绝对偏差（MAD）
        data['MAD'] = data['TP'].rolling(window=period).apply(lambda x: np.fabs(x - x.mean()).mean(), raw=False)
        # 计算 CCI
        data['CCI'] = (data['TP'] - data['SMA']) / (0.015 * data['MAD'])
        # 生成买卖信号
        data['Buy_Signal'] = np.where(data['CCI'] < -100, 1, 0)
        data['Sell_Signal'] = np.where(data['CCI'] > 100, 1, 0)
        return data

class ROC(BASIC_STRATEGY):
    def update(self, data):
        period=12
        rocma_period=6
        # 计算 ROC 值
        data['ROC'] = (data['close'] - data['close'].shift(period)) / data['close'].shift(period) * 100
        # 计算 ROC 的移动平均线（ROCMA）
        data['ROCMA'] = data['ROC'].rolling(window=rocma_period).mean()
        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['ROC'] > 0) & (data['ROC'].shift() <= 0), 1, 0)
        data['Sell_Signal'] = np.where((data['ROC'] < 0) & (data['ROC'].shift() >= 0), 1, 0)
        return data

class BOLL(BASIC_STRATEGY):
    def update(self, data):
        period = 20
        std_dev = 2
        data['MA'] = data['close'].rolling(window=period).mean()
        data['STD'] = data['close'].rolling(window=period).std()
        data['UpperBand'] = data['MA'] + std_dev * data['STD']
        data['LowerBand'] = data['MA'] - std_dev * data['STD']

        data['Buy_Signal'] = np.where(data['close'] < data['LowerBand'], 1, 0)
        data['Sell_Signal'] = np.where(data['close'] > data['UpperBand'], 1, 0)
        return data

class EXPMA(BASIC_STRATEGY):
    def update(self, data):
        short_period=12
        long_period=26
        # 计算短期和长期 EXPMA
        data['EXPMA_short'] = data['close'].ewm(span=short_period, adjust=False).mean()
        data['EXPMA_long'] = data['close'].ewm(span=long_period, adjust=False).mean()

        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['EXPMA_short'] > data['EXPMA_long']) &
                                      (data['EXPMA_short'].shift() <= data['EXPMA_long'].shift()), 1, 0)
        data['Sell_Signal'] = np.where((data['EXPMA_short'] < data['EXPMA_long']) &
                                       (data['EXPMA_short'].shift() >= data['EXPMA_long'].shift()), 1, 0)
        return data

class ENE(BASIC_STRATEGY):
    def update(self, data, period=10, m1=1.25, m2=0.75):
        # 计算中轨（ENE）
        data['ENE'] = data['close'].ewm(span=period, adjust=False).mean()

        # 计算标准差（SD）
        data['SD'] = data['close'].rolling(window=period).std()

        # 计算上轨（UPPER）和下轨（LOWER）
        data['UPPER'] = data['ENE'] + m1 * data['SD']
        data['LOWER'] = data['ENE'] - m2 * data['SD']

        # 生成买卖信号
        data['Buy_Signal'] = np.where(
            (data['close'] > data['LOWER']) & (data['close'].shift() <= data['LOWER'].shift()), 1, 0)
        data['Sell_Signal'] = np.where(
            (data['close'] < data['UPPER']) & (data['close'].shift() >= data['UPPER'].shift()), 1, 0)
        return data

class BBI(BASIC_STRATEGY):
    def update(self, data):
        short_period = 3
        medium_period = 6
        long_period = 12
        extra_long_period = 24
        data['MA3'] = data['close'].rolling(window=short_period).mean()
        data['MA6'] = data['close'].rolling(window=medium_period).mean()
        data['MA12'] = data['close'].rolling(window=long_period).mean()
        data['MA24'] = data['close'].rolling(window=extra_long_period).mean()
        data['BBI'] = (data['MA3'] + data['MA6'] + data['MA12'] + data['MA24']) / 4
        # 生成买卖信号
        data['Buy_Signal'] = np.where((data['BBI'] < data['close']) & (data['BBI'].shift() >= data['close'].shift()),
                                       1, 0)
        data['Sell_Signal'] = np.where((data['BBI'] > data['close']) & (data['BBI'].shift() <= data['close'].shift()), 1,
                                      0)

        return data

# class BOLL_MACD(BASIC_STRATEGY):
#     def update(self, data):
#         short_period = 3
#         medium_period = 6
#         long_period = 12
#         extra_long_period = 24
#         data['MA3'] = data['close'].rolling(window=short_period).mean()
#         data['MA6'] = data['close'].rolling(window=medium_period).mean()
#         data['MA12'] = data['close'].rolling(window=long_period).mean()
#         data['MA24'] = data['close'].rolling(window=extra_long_period).mean()
#         data['BBI'] = (data['MA3'] + data['MA6'] + data['MA12'] + data['MA24']) / 4
#         # 生成买卖信号
#         data['Buy_Signal'] = np.where(
#             (data['BBI'] < data['close']) & (data['BBI'].shift() >= data['close'].shift()),
#             1, 0)
#         data['Sell_Signal'] = np.where(
#             (data['BBI'] > data['close']) & (data['BBI'].shift() <= data['close'].shift()), 1,
#             0)
#         return data